// CommandLineHelper Library
// =========================
// License: Microsoft Permissive License (Ms-PL) v1.1
// Author: Rhy Mednick (http://www.rhyverse.net)
// Project Site: http://www.codeplex.com/CommandLineHelper

using System;
using System.Collections.Generic;
using System.Text;

namespace CommandLineHelper.Attributes
{
    /// <summary>
    /// When applied to a property, this attribute instructs the command line helper parsing routine to validate 
    /// that the property value passed in exists in the enumeration that defines the property. This can only be 
    /// applied to properties defined as enumerations.
    /// </summary>
    [AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = false)]
    public sealed class ValidateEnumeratedArgumentsAttribute : Attribute, IValidation
    {
        private string m_statusMessage = String.Empty;
        /// <summary>
        /// Gets the status message that is set when the IsValid() method is called.
        /// </summary>
        public string StatusMessage
        {
            get
            {
                return m_statusMessage;
            }
        }

        /// <summary>
        /// Verifies that the passed value is part of the enumerated property that this attribute decorates.
        /// </summary>
        /// <param name="value">The value to validate.</param>
        /// <returns>True if the value is contained in the enumeration and false if it isn't.</returns>
        public bool IsValid(object value)
        {
            //first, verify that object is an enumeration
            Type type = value.GetType();
            bool retval = false;
            if (type.IsEnum)
            {
                if (Enum.IsDefined(type, value))
                {
                    retval = true;
                }
                else
                {
                    //if we don't have a match, let's make sure we don't have a compound item before we fail
                    if (value.ToString().Contains(","))
                    {
                        //if we have an enum, which we know we do because of the earlier check, 
                        //and ToString() returns a value with a comma, then it must be valid.
                        //if it wasn't valid then we would have gotten an integer in string format
                        //from the ToString() method.
                        retval = true;
                    }
                }
            }
            if (!retval)
            {
                m_statusMessage = String.Format("The value '{0}' is not defined in the {1} enumeration.", (int)value, type.Name);
            }
            return retval;
        }
    }
}
